package net.yongjinman.app.android.util;

import android.os.Debug;
import android.util.Log;

public class PrintLog {

	// log part
	public static final int LOG_PART_UI = 0x00000001; // ui part
	public static final int LOG_PART_INPUT = 0x00000002; // input part
	public static final int LOG_PART_SYSTEM = 0x00001000; // system part
	public static final int LOG_PART = LOG_PART_UI | LOG_PART_INPUT | LOG_PART_SYSTEM;
	
	public static final int LOG_LEVEL_1 = 1; // low
	public static final int LOG_LEVEL_2 = 2;
	public static final int LOG_LEVEL_3 = 3;
	public static final int LOG_LEVEL_4 = 4;
	public static final int LOG_LEVEL_5 = 5; // height
	public static final int LOG_LEVEL = LOG_LEVEL_5;
	
	public static final String LOG_TAG = "SignBall"; // log tag
	
	public static void printNativeMemory() {
		try {
			printNativeMemory(""); 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void printNativeMemory(String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print("I", 1, LOG_PART_SYSTEM, log+"["+(Debug.getNativeHeapSize()/1024)+"K/"+
					(Debug.getNativeHeapFreeSize()/1024)+"K/"+(Debug.getNativeHeapAllocatedSize()/1024)+
					"K|Total/Free/Allocated]", caller); 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void printUI(String div, int logLevel, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, LOG_PART_UI, logLevel, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void printUIError(String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print("E", LOG_PART_UI, LOG_LEVEL_1, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void printInput(String div, int logLevel, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, LOG_PART_INPUT, logLevel, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void printSystem(String div, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, LOG_PART_SYSTEM, LOG_LEVEL_5, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void printSystem(String div, int logLevel, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, LOG_PART_SYSTEM, logLevel, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void print(String div, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, LOG_PART, LOG_LEVEL, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void print(String div, int logPart, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, logPart, LOG_LEVEL, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void print(String div, int logPart, int level, String log) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print(div, logPart, level, log, caller);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void print(String div, int logPart, int level, String log, String caller) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			if(caller == null) {
				caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			}
			if(!Consts.DEBUG) {
				return;
			}
			if(level > LOG_LEVEL) {
				return;
			}
			if((logPart & LOG_PART) == 0) {
				return;
			}
			if ( div.equals("V") ) {
				Log.v( LOG_TAG, log + " <"+caller+">" );
			} else if ( div.equals("I") ) {
				Log.i( LOG_TAG, log + " <"+caller+">" );
			} else if ( div.equals("D") ) {
				Log.d( LOG_TAG, log + " <"+caller+">" );
			} else if ( div.equals("W") ) {
				Log.w( LOG_TAG, log + " <"+caller+">" );
			} else if ( div.equals("E") ) {
				Log.e( LOG_TAG, log );
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static final void print ( Exception e ) {
		try {
			StackTraceElement[] stacks = new Throwable().getStackTrace();
			String caller = stacks[1].getClassName()+"."+stacks[1].getMethodName()+"."+stacks[1].getLineNumber();
			print( "E", LOG_PART, LOG_LEVEL, "["+e.getLocalizedMessage()+"] "+e.toString(), caller); 
			
			for( int i = 0 ; i < e.getStackTrace().length ; i++ ) {
				print( "E", LOG_PART, LOG_LEVEL, e.getStackTrace()[i].toString(), caller);
				if ( i > 14 ) break;
			}
		} catch ( Exception e1 ) {}
	}

}
